/*
	Copyright (c) 2012 Canadensys
*/
package net.canadensys.dataportal.vascan.downloads;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.canadensys.dataportal.utils.HibernateUtil;
import net.canadensys.dataportal.vascan.LookupManager;
import net.canadensys.dataportal.vascan.config.impl.InstallationConfig;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.Session;

/**
 * This class is the entry point to create text file containing the result of a query.
 * The file will be tab separated.
 */
public class TextFileManager {
	private ResourceBundle _bundle = null;
	
	public TextFileManager(ResourceBundle bundle){
		this._bundle = bundle;
	}
	
	public boolean generateCSV(String destinationFilePath, String[] province, String combination, String habit, Integer taxonId, String[] distributionStatus,
			String[] rank, String hybrids, String sort){
		
		if(StringUtils.isBlank(destinationFilePath)){
			return false;
		}
		
		Session hibernateSession = HibernateUtil.getSessionFactory().getCurrentSession();
	    hibernateSession.beginTransaction();
	    boolean success = true;
		
		// csv file
	    StringBuilder csv = new StringBuilder("");
	    
	    String      delimiter = "\t";
	    String      newline = "\n";
	    
	    // csv file columns headers
	    csv.append("URL").append(delimiter);
	    csv.append(_bundle.getObject("rank")).append(delimiter);
	    csv.append(_bundle.getObject("scientific_name")).append(delimiter);
	    csv.append(_bundle.getObject("vernacular_fr")).append(delimiter);
	    csv.append(_bundle.getObject("vernacular_en")).append(delimiter);
	    csv.append(_bundle.getObject("habitus")).append(delimiter);
	    csv.append(_bundle.getObject("province_BC")).append(delimiter);
	    csv.append(_bundle.getObject("province_AB")).append(delimiter);
	    csv.append(_bundle.getObject("province_SK")).append(delimiter);
	    csv.append(_bundle.getObject("province_MB")).append(delimiter);
	    csv.append(_bundle.getObject("province_ON")).append(delimiter);
	    csv.append(_bundle.getObject("province_QC")).append(delimiter);
	    csv.append(_bundle.getObject("province_NB")).append(delimiter);    
	    csv.append(_bundle.getObject("province_PE")).append(delimiter);
	    csv.append(_bundle.getObject("province_NS")).append(delimiter);
	    csv.append(_bundle.getObject("province_NL_N")).append(delimiter);
	    csv.append(_bundle.getObject("province_NL_L")).append(delimiter);
	    csv.append(_bundle.getObject("province_PM")).append(delimiter);
	    csv.append(_bundle.getObject("province_YT")).append(delimiter);
	    csv.append(_bundle.getObject("province_NT")).append(delimiter);
	    csv.append(_bundle.getObject("province_NU")).append(delimiter);
	    csv.append(_bundle.getObject("province_GL"));
	    
	    //make sure the taxonId was initialised
	    if(taxonId != -1){
	        boolean returnCountOnly = false;
	        int limitResultsTo = 0;
	        ResultSet rs = LookupManager.getDistributions(returnCountOnly, limitResultsTo, combination, habit, taxonId, province, distributionStatus, rank, hybrids, sort);
   
	        if(rs !=null){
	        	try{
		            rs.beforeFirst();
		            while(rs.next()){
		            	csv.append(newline);
		            	csv.append(InstallationConfig.getInstance().get(InstallationConfig.VASCAN_ROOT_URL_KEY)).append("taxon/").append(rs.getInt("taxonid")).append(delimiter);
		                csv.append(_bundle.getObject("rank_"+rs.getString("rank"))).append(delimiter);
		                String fsn = rs.getString("calname");
		                StringBuffer sb = new StringBuffer("");
		                Pattern p = Pattern.compile("<\\/?[a-zA-Z][^>]*>" ,Pattern.CASE_INSENSITIVE);
		                Matcher m = p.matcher(fsn);
		                while (m.find()) {
		                    m.appendReplacement(sb,"");
		                }
		                m.appendTail(sb);
		                csv.append(sb.toString()).append(delimiter);
		                
		                //Accepted vernacular names
		                if(rs.getString("vernacularfr") != null){
		                	csv.append(rs.getString("vernacularfr"));
		                }
		                csv.append(delimiter);
		                if(rs.getString("vernacularen") != null){
		                	csv.append(rs.getString("vernacularen"));
		                }
		                csv.append(delimiter);
		                
		                String habituses = rs.getString("calhabit");
		                StringBuffer taxonHabitus = new StringBuffer("");
		                String splitHabituses[] = habituses.split(",");
		                if(splitHabituses != null){
		                    for(String h : splitHabituses){
		                    	if(taxonHabitus.length() > 0)
		                    		taxonHabitus.append(" ");
		                    	taxonHabitus.append(_bundle.getObject("habitus_"+h));
		                    }
		                    csv.append(taxonHabitus.toString());
		                }
	
		                csv.append(delimiter);
		                csv.append(_bundle.getObject("distribution_"+rs.getString("BC"))).append(delimiter);
		                csv.append(_bundle.getObject("distribution_"+rs.getString("AB"))).append(delimiter);
		                csv.append(_bundle.getObject("distribution_"+rs.getString("SK"))).append(delimiter);
		                csv.append(_bundle.getObject("distribution_"+rs.getString("MB"))).append(delimiter);
		                csv.append(_bundle.getObject("distribution_"+rs.getString("ON"))).append(delimiter);
		                csv.append(_bundle.getObject("distribution_"+rs.getString("QC"))).append(delimiter);
		                csv.append(_bundle.getObject("distribution_"+rs.getString("NB"))).append(delimiter);
		                csv.append(_bundle.getObject("distribution_"+rs.getString("PE"))).append(delimiter);
		                csv.append(_bundle.getObject("distribution_"+rs.getString("NS"))).append(delimiter);
		                csv.append(_bundle.getObject("distribution_"+rs.getString("NL_N"))).append(delimiter);
		                csv.append(_bundle.getObject("distribution_"+rs.getString("NL_L"))).append(delimiter);
		                csv.append(_bundle.getObject("distribution_"+rs.getString("PM"))).append(delimiter);
		                csv.append(_bundle.getObject("distribution_"+rs.getString("YT"))).append(delimiter);
		                csv.append(_bundle.getObject("distribution_"+rs.getString("NT"))).append(delimiter);
		                csv.append(_bundle.getObject("distribution_"+rs.getString("NU"))).append(delimiter);
		                csv.append(_bundle.getObject("distribution_"+rs.getString("GL")));
		            }       
	        	}
	        	catch (SQLException sqlEx) {
	        		Logger.getLogger(TextFileManager.class.getName()).log(Level.SEVERE, "Can't generate text file. ", sqlEx);
		        	return false;
				}
	        	finally{
	        		if(rs != null){
	        			try {
							rs.close();
							// hibernateSession.getTransaction().commit();??
						} catch (SQLException e) {}
	        		}
	        	}
	        }
	    
		    File file = new File(destinationFilePath);
		    BufferedWriter bw = null;
		    try{
			    FileOutputStream fos = new FileOutputStream(file);
			    bw = new BufferedWriter(new OutputStreamWriter(fos, "UTF-8"));
			    bw.write(csv.toString());
			    bw.close();
			    bw = null;
			    fos.close();
		    }
		    catch (IOException e) {
		    	success = false;
				e.printStackTrace();
			}
			finally{
				if(bw != null){
					try {
						bw.close();
					} catch (IOException e) {}
				}
			}
	    }
	    hibernateSession.getTransaction().commit();
	    return success;
	}
}
